home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
asm
/
alib11b.zip
/
CODE1.ZIP
/
DISKINFO
/
TRANSFER.ASM
< prev
Wrap
Assembly Source File
|
1994-10-04
|
7KB
|
272 lines
;-----------------------------------------------------------------------
; LOW LEVEL DISK DRIVERS
;-----------------------------------------------------------------------
; INPUTS - ax=cluster#
; es=storage area
; cx=number of clusters to read
;
; OUTPUT - carry set if error
; all registers destroyed except for segment registers
;
read_clusters:
test ax,07
jnz rcs4 ;jump if not display trigger
push ax
push bx
push si
mov dx,display_position3
call display_dec_word_at_posn
pop si
pop bx
pop ax
rcs4: sub ax,2 ;force cluster count range (0 +)
mul cs:sectors_per_cluster ;compute sector#
sub bp,bp
add ax,cs:boot_fat_dir_size ;add number sectors in header
adc bp,dx ;add in carry
push ax ;save sector#
mov ax,cx
mul cs:sectors_per_cluster ;compute # of sectors to read
mov cx,ax ; -cx- = # of sectors to read
pop dx ; -dx- = sector #
sub bx,bx ;set buffer offset to zero
call read_sectors
ret
;-------------------------------------------------------------------------
; read sectors
; inputs: cs:drive_number
; es:bx = buffer
; cx = number of sectors to read
; bp = relative sector number (high word)
; dx = relative sector number (low word)
; outputs: carry set if error
;
read_sectors:
push si
push di
push ds
mov al,cs:drive_number
mov cs:buffer_sav,bx
mov cs:seg_sav,es
mov cs:count_sav,cx
mov cs:sector_adr_sav,dx
mov cs:sector_adr_sav+2,bp
push es
pop ds
int 25h ;absoulute read
inc sp ;clear stack
inc sp ;clear stack
cld ;restore direction
jnc read_sectors_exit1 ;jmp if read ok
;
; first read failed. If this is a DOS4+ extended partition (over 33meg) then
; we must use an alternate format for int 25
;
push cs
pop ds
mov al,cs:drive_number
mov bx,offset dos4_int25_pkt
mov cx,-1 ;sector# not here
int 25h ;absoulute read
pop ax ;clear stack
cld ;restore direction
jnc read_sectors_exit1
mov cs:bad_sector,dx ;save bad sector#
cmp cs:test_mode,0 ;check if real thing
je read_sectors_exit1 ; and keep going if it is
or cs:abort_flag,1
stc
read_sectors_exit1:
pop ds
pop di
pop si
read_exit:
ret
;---------------------
; read cluster using fat
; INPUTS - ax = fat ptr
; es = storage area
;
; OUTPUT - carry set if error
; ax = ffff if last read was at end of fat chain.
; else, ax points at next fat entry
;
read_using_fat:
push es
call fat_lookup ;look up cluster in fat
pop es
push bx ;save next cluster number
mov cx,1 ;read one cluster
call read_clusters
pop ax ;get next cluster number
ret
;---------------------
; INPUTS - ax=cluster#
; es=storage area
; cx=number of clusters to write
; OUTPUT - carry set if error
; all registers destroyed except for ES & DS
;
write_clusters:
test ax,07
jnz wcs4 ;jump if not display trigger
push ax
push bx
push si
mov dx,display_position1
call display_dec_word_at_posn
pop si
pop bx
pop ax
wcs4: sub ax,2 ;force cluster count range (0 +)
mul cs:sectors_per_cluster ;compute sector#
sub bp,bp
add ax,cs:boot_fat_dir_size ;add number sectors in header
adc bp,dx ;add any carry
push ax ;save sector#
mov ax,cx
mul cs:sectors_per_cluster ;compute # of sectors to write
mov cx,ax ; -cx- = # of sectors to write
pop dx ; -dx- = sector #
call write_sectors
ret
;---------------------------
; INPUTS - cx = number of sectors to write
; bp,dx = sector number
; es:bx = data buffer
; drive_number
; OUTPUTS- carry set if error
;
write_sectors:
push si
push di
push ds
cmp cs:test_mode,0 ;check if test mode
jnz write_bypass ; and skip write if true
sub bx,bx
mov al,cs:drive_number
mov cs:buffer_sav,bx
mov cs:seg_sav,es
mov cs:count_sav,cx
mov cs:sector_adr_sav,dx
mov cs:sector_adr_sav+2,bp
push es
pop ds
int 26h ;absoulute write
inc sp ;clear stack
inc sp ;clear stack
cld ;restore direction
jnc writ_exit ; jmp if read ok
;
; first writ failed. If this is a DOS4+ extended partition (over 33meg) the
; we must use an alternate format for int 25
;
push cs
pop ds
mov al,cs:drive_number
mov bx,offset dos4_int25_pkt
mov cx,-1 ;sector# not here
int 26h ;absoulute read
pop ax ;clear stack
cld ;restore direction
jnc writ_exit
mov cs:bad_sector,dx
or cs:abort_flag,2
jmp writ_exit
write_bypass:
clc
writ_exit:
pop ds
pop di
pop si
ret
;------------------------------
; look up cluster in fat
; INPUTS - ax = fat ptr from dir
; OUTPUT - ax = cluster number
; bx = next cluster number
; es = fat segment
fat_lookup:
mov es,cs:fat_segment
cmp cs:fat_type,1 ;check if 12-bit fat
je twelve_bit_fat ;jump if 12-bit fat
;
; 16-bit fat
;
mov bx,ax ;get fat ptr (cluster #)
shl bx,1 ;convert to word index
mov bx,es:[bx] ;get next fat ptr
ret
twelve_bit_fat:
mov bx,ax
shr bx,1
pushf
add bx,ax
mov bx,es:[bx] ;get fat data
popf ;get odd/even state
jnc twelve1 ;jump if even fat entry
shr bx,1
shr bx,1
shr bx,1
shr bx,1
twelve1:and bx,0fffh
jz twelve3 ;jump if fat=0
cmp bx,0ff7h ;check if end
jl twelve3 ;jump if not end of chain
jne twelve2 ;jump if end of chain
mov bx,0fff7h ;get locked out cluster code
jmp short twelve3
twelve2:
mov bx,0ffffh ;set end of chain state
twelve3:ret
;-------------------------------
; fat_write
; INPUTS - ax = fat (cluster#)
; bx = new data
;
fat_write:
push es
push bx
mov es,cs:fat_segment
cmp cs:fat_type,1 ;check if 12-bit fat
je twelv_bit_fat ;jump if 12-bit fat
;
; 16-bit fat
;
mov bx,ax ;get fat ptr (cluster #)
shl bx,1 ;convert to word index
pop ax
mov es:[bx],ax ;store new fat ptr
pop es
ret
twelv_bit_fat:
mov bx,ax
shr bx,1
pushf ;save carry flag
add bx,ax ;compute fat address
mov cx,es:[bx] ;get current fat data
popf ;restore carry flag
pop ax ;restore new fat data
jnc twelv1 ;jump if even fat
and ax,0fffh ;force 12bit value
shl ax,1
shl ax,1
shl ax,1
shl ax,1
and cx,000fh ;remove old fat data
or cx,ax
mov es:[bx],cx
pop es
ret
twelv1:
and ax,0fffh ;force 12-bit value
and cx,0f000h ;remove old fat data
or cx,ax
mov es:[bx],cx
pop es
ret
;-----------------------------------------------------------------------